<?php
require_once 'OAuth/OAuthException.php';
require_once 'OAuth/OAuthServer.php';

/**
 * Class RestController
 *
 * Description for class RestController
 *
 * @author: langxangvn
*/
class ApiOAuthController extends Zend_Controller_Action {
	/**
	 * This is method init
	 *
	 * @return mixed This is the return value description
	 *
	 */
	public function init() {
		/* Initialize action controller here */
	}
	
	/**
	 * indexAction
	 *
	 * @return void
	 */
	public function indexAction() {		
		$this->view->title = "Welcome to REST API web services";
		$this->view->headTitle($this->view->title);
		
		$server = new OAuthServer();
		try {
			// Get the user info from the storage (session)  
			$storage = Zend_Auth::getInstance()->getStorage();	// storage of Zend_Auth
			$user = $storage->read();
			$this->view->user = $user;
			
			if(Zend_Auth::getInstance()->hasIdentity()) {
				$email = $server->verify('request', true);
				if(!$email) {
					$this->_forward('authorize');
				} else {
					$this->view->authorized = true;
				}
			} else {	// if not logged in, redirect to login form						
				$this->_forward('login');
			}
		} catch(Exception $e) {			
			$this->view->message = $e->getMessage();
		}
	}
	
	/**
	 * This is method loginAction
	 *
	 * @return void
	 *
	 */
	public function loginAction() 
	{		
		// already logged in
		if(Zend_Auth::getInstance()->hasIdentity()) {
			// forward to index
			$this->_forward('index');
		}
		
		// make sure get action only from index
		if (!$this->getRequest()->isPost()) {		// not is POST
			if($this->getRequest()->getPathInfo() != '/auth/' &&
				$this->getRequest()->getPathInfo() != '/auth/index/')	// not is index forward
			{
				// re-forward to index
				$this->_forward('index');
			}
		}
		
		$this->view->title = "Please login to use REST API web services";
		$this->view->headTitle($this->view->title);
		
		$form = new Form_Login();
		$form->setAction('/public/auth/login/' . $params)
			->setMethod('POST');
		
		if ($this->getRequest()->isPost()) {
			$data = $this->_request->getPost();		
			if ($form->isValid($data)) {			
				$user = new Model_DbTable_Users();				
				$email = $form->getValue('auth_email');
				$password = $form->getValue('auth_password');
				
				// try login
				if (true === $message = $user->login($email, $password)) {
					// re-forward to index
					$this->_forward('index');
				} else {
					// Set errors
					$this->view->errors = $message;
				}				
			} else {
				$form->populate($data);					
			}
		}
		
		$this->view->form = $form;
	}		

	/**
	 * This is method logoutAction
	 *
	 * @return void
	 *
	 */
	public function logoutAction()
	{
		// shutdown view script and layout
		$this->_helper->viewRenderer->setNoRender(true);
		Zend_Layout::getMvcInstance()->disableLayout();
		
		$auth = Zend_Auth::getInstance();	
		// delete the information from the session
		$auth->clearIdentity();		
		Zend_Session::forgetMe();
		
		// redirect to home
		$this->_redirect(null);
	}
		
	/**
	 * indexAction
	 *
	 * @return void
	 */
	public function requestTokenAction() {
		$this->handle('requestToken');
	}
	
	/**
	 * indexAction
	 *
	 * @return void
	 */
	public function authorizeAction() {							
		if(!Zend_Auth::getInstance()->hasIdentity()) {		// not logged in		
			$this->_forward('index');	// forward to index
		}
		
		// make sure get action only from index
		if (!$this->getRequest()->isPost()) {			// not is POST
			if($this->getRequest()->getPathInfo() != '/auth/' && 
				$this->getRequest()->getPathInfo() != '/auth/index/') // not forward from index
			{
				$this->_forward('index');
			}
		}
		
		$this->view->title = "Please authorize to use REST API web services";
		$this->view->headTitle($this->view->title);
		
		$form = new Form_Authorize();
		$form->setAction('/public/auth/authorize/' . $params)
			->setMethod('POST');				
		
		if ($this->getRequest()->isPost()) {
			$data = $this->_request->getPost();		
			if($data['commit']) {				
				$authorized = true;
			} else {
				$authorized = false;
			}
			
			try {
				// Get the user info from the storage (session)  
				$storage = Zend_Auth::getInstance()->getStorage();	// storage of Zend_Auth
				$user = $storage->read();
								
				// initialize API request
				$server = new OAuthServer();
				$server->authorizeVerify();
				$server->authorizeFinish($authorized, $user->email);
				
				if($authorized) {	// accepted						
					// redirect to index	
					$this->_redirect('/auth/' . $params);
				} else {
					// denied
					$this->_redirect(null);	
				}
			} catch(Exception $e) {			
				// Redirect to index	
				$this->_redirect('/auth/' . $params);
			}
		}
		
		$this->view->form = $form;		
	}
	
	/**
	 * indexAction
	 *
	 * @return void
	 */
	public function accessTokenAction() {
		$this->handle('accessToken');
	}
	
	/**
	 * *
	 *
	 * @param mixed $action This is a description
	 * @return mixed This is the return value description
	 *
	 */	
	protected function handle($action) {
		$this->_helper->Layout->disableLayout();		// disble layout
		$this->_helper->ViewRenderer->setNoRender();	// no renderer
		
		$params = $this->_request->getParams();
		unset($params['controller']);
		unset($params['action']);
		unset($params['module']);
		
		if (!array_key_exists(OAuthRequest::$API_FORMAT, $params)){
			$format = 'json';
		} else {
			$format = $params[OAuthRequest::$API_FORMAT];
		}
		
		switch ($format) {
			case 'xml':;
				$this->_response->setHeader('Content-Type', 'text/xml');
				break;
			
			case 'plain-text':				
				$this->_response->setHeader('Content-Type', 'text/html');
				break;
			
			case 'json':			
				$this->_response->setHeader('Content-Type', 'application/json');
				break;
			
			default:
				$this->_response->setHeader('Content-Type', 'application/json');
		}	
		
		try {
			$server = new OAuthServer();
			
			$result = false;
			if($action === 'accessToken') {
				$isSSL = isset($_SERVER['HTTPS']);	// check if is SSL or not
				$xauthMode = $server->getParam(OAuthRequest::$X_AUTH_MODE);
				$xauthPassword = $server->getParam(OAuthRequest::$X_AUTH_PASSWORD);
				$xauthUsername = $server->getParam(OAuthRequest::$X_AUTH_USERNAME);	
				$isXAuth = !(empty($xauthUsername) || empty($xauthPassword)) && 
					($xauthMode === "client_auth");				
				
				if($isXAuth) {
					$result = $server->handle('clientAuth');
				} else {
					$result = $server->handle('accessToken');
				}
			} else {
				$result = $server->handle($action);
			}
			
			switch ($format) {
				case 'xml':
					$response = OAuthResponse::generate(array('result' => $result));
					break;
				
				case 'plain-text':				
					$response = OAuthResponse::plain($result);
					break;
				
				case 'json':
					$response = Zend_Json::encode($result);	
					break;
				
				default:
					$format = 'json';
					$code = OAuthRequestVerifier::$UNSUPPORTED_RESPONSE_FORMAT;
					$error = $server->getErrorMessage($code);
					throw new OAuthException($error, $code);
			}			
			
			$this->_response->setBody($response);
		} catch(OAuthException $e) {
			$error = $server->fault($e, $format);
			$this->_response->setBody($error);
		} catch(Exception $e) {
			$error = $server->fault($e, $format);
			$this->_response->setBody($error);
			$this->_response->setRawHeader('HTTP/1.0 400 Bad Request');		
		}
	}
}
?>